package com.lin.gameserver.handler;

import com.google.protobuf.InvalidProtocolBufferException;
import com.lin.gameserver.protobuf.CommandId;
import com.lin.gameserver.protobuf.ErrorCode;
import com.lin.gameserver.protobuf.MessageWrapper;
import com.lin.gameserver.session.GameSession;
import com.lin.gameserver.session.SessionManager;
import com.lin.gameserver.websocket.MessageLogger;
import com.lin.proto.ReqLoginMessage;
import com.lin.proto.ResLoginMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 登录消息处理器
 */
public class LoginHandler implements MessageHandler {
    private static final Logger logger = LoggerFactory.getLogger(LoginHandler.class);
    
    @Override
    public int getCommandId() {
        return CommandId.CMD_LOGIN_REQ;
    }
    
    @Override
    public boolean handle(GameSession session, MessageWrapper wrapper) {
        try {
            long startTime = System.currentTimeMillis();
            
            // 解析登录请求
            ReqLoginMessage request = wrapper.parseRequestBody(ReqLoginMessage.parser());
            
            // 处理登录逻辑
            int loginType = request.getLoginType();
            String token = request.getToken();
            String sessionId = !request.getSessionId().isEmpty() ? request.getSessionId() : null;
            
            logger.info("Login request: type={}, token={}, sessionId={}", loginType, maskToken(token), sessionId);
            
            // 这里简单的登录验证，实际项目中应该连接数据库或认证服务
            boolean loginSuccess = validateLogin(token);
            int playerId = 0;
            
            if (loginSuccess) {
                // 假设从token中获取账号信息，这里简单从token分割，假设格式为"username:password"
                String account = token.split(":")[0];
                
                // 生成玩家ID，这里简单使用account的hashCode
                playerId = Math.abs(account.hashCode());
                
                // 更新会话认证信息
                SessionManager.getInstance().authenticateSession(session.getSessionId(), playerId, account);
                
                logger.info("Login success: playerId={}, account={}", playerId, account);
            } else {
                logger.warn("Login failed: token={}", maskToken(token));
            }
            
            // 构建登录响应
            ResLoginMessage.Builder responseBuilder = ResLoginMessage.newBuilder()
                    .setLoginSuccess(loginSuccess)
                    .setPlayerId(playerId);
            
            // 如果登录成功，返回会话ID
            if (loginSuccess) {
                responseBuilder.setSessionId(session.getSessionId());
                
                // 在选项中设置会话ID，部分客户端可能通过这种方式获取会话ID
                wrapper.addOption(CommandId.OPT_SESSION_ID, session.getSessionId());
            }
            
            // 设置响应消息
            wrapper.setResponseBody(responseBuilder.build());
            
            // 记录处理时间
            long processTime = System.currentTimeMillis() - startTime;
            MessageLogger.logProcessTime(session.getSessionId(), wrapper.getCmd(), processTime);
            
            return true;
        } catch (InvalidProtocolBufferException e) {
            logger.error("Failed to parse login request", e);
            wrapper.setErrorCode(ErrorCode.ERROR_PROTOCOL);
            return false;
        } catch (Exception e) {
            logger.error("Error processing login request", e);
            wrapper.setErrorCode(ErrorCode.ERROR_SYSTEM_UNKNOWN);
            return false;
        }
    }
    
    @Override
    public boolean requireAuthentication() {
        // 登录消息不需要认证
        return false;
    }
    
    /**
     * 验证登录信息
     *
     * @param token 登录令牌
     * @return 是否验证通过
     */
    private boolean validateLogin(String token) {
        // 简单的登录验证，实际项目中应该连接数据库或认证服务进行验证
        // 这里假设token格式为"username:password"，并且只要username和password都不为空就算验证通过
        if (token == null || token.isEmpty()) {
            return false;
        }
        
        String[] parts = token.split(":");
        if (parts.length != 2) {
            return false;
        }
        
        String username = parts[0];
        String password = parts[1];
        
        return !username.isEmpty() && !password.isEmpty();
    }
    
    /**
     * 隐藏token中的敏感信息
     *
     * @param token 原始token
     * @return 隐藏后的token
     */
    private String maskToken(String token) {
        if (token == null || token.isEmpty()) {
            return "";
        }
        
        // 假设token格式为"username:password"，隐藏password部分
        int index = token.indexOf(':');
        if (index > 0 && index < token.length() - 1) {
            return token.substring(0, index + 1) + "******";
        }
        
        // 如果token不是预期格式，则隐藏大部分字符
        if (token.length() <= 4) {
            return "******";
        } else {
            return token.substring(0, 2) + "******" + token.substring(token.length() - 2);
        }
    }
} 